﻿using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using AdDuplex;
using MC.Phone.Ads.Provider;
using MC.Phone.Ads.Utils;
using AdDuplexAdControl = AdDuplex.AdControl;

namespace MC.Phone.Ads.AdDuplex
{
    public class AdDuplexAdProvider : BaseAdProvider
    {
        public static readonly DependencyProperty AppProperty =
            DependencyProperty.Register("App", typeof (string), typeof (AdDuplexAdProvider), null);

        private WeakEventListener<AdDuplexAdProvider, object, AdClickEventArgs> _adClickListener;
        private WeakEventListener<AdDuplexAdProvider, object, AdLoadedEventArgs> _adLoadedListener;
        private WeakEventListener<AdDuplexAdProvider, object, AdLoadingErrorEventArgs> _adLoadingErrorListener;

        [Category("Ad")]
        public string App
        {
            get { return (string) GetValue(AppProperty); }
            set { SetValue(AppProperty, value); }
        }

        public override string Name
        {
            get { return "AdDuplex"; }
        }

        /// <summary>
        /// Not supported by AdDuplex.
        /// </summary>
        public override string CountryCode { set; protected get; }

        public override FrameworkElement ProvideAd()
        {
            var control = new AdDuplexAdControl
                                        {
                                            AppId = App,
                                            IsTest = IsTest,
                                        };
            _adClickListener = new WeakEventListener<AdDuplexAdProvider, object, AdClickEventArgs>(this)
                                   {
                                       OnEventAction = (instance, source, args) => instance.AdClick(),
                                       OnDetachAction = weak => control.AdClick -= weak.OnEvent
                                   };
            control.AdClick += _adClickListener.OnEvent;
            _adLoadedListener = new WeakEventListener<AdDuplexAdProvider, object, AdLoadedEventArgs>(this)
                                    {
                                        OnEventAction = (instance, source, args) => instance.AdLoaded(),
                                        OnDetachAction = weak => control.AdLoaded -= weak.OnEvent
                                    };
            control.AdLoaded += _adLoadedListener.OnEvent;
            _adLoadingErrorListener =
                new WeakEventListener<AdDuplexAdProvider, object, AdLoadingErrorEventArgs>(this)
                    {
                        OnEventAction = (instance, source, args) => instance.AdLoadingError(args),
                        OnDetachAction = weak => control.AdLoadingError -= weak.OnEvent
                    };
            control.AdLoadingError += _adLoadingErrorListener.OnEvent;
            return control;
        }

        public override void Clean()
        {
            _adClickListener = _adClickListener.DetachToNull();
            _adLoadedListener = _adLoadedListener.DetachToNull();
            _adLoadingErrorListener = _adLoadingErrorListener.DetachToNull();
        }

        private void AdLoadingError(AdLoadingErrorEventArgs e)
        {
            OnAdError(e.Error);
        }

        private void AdLoaded()
        {
            OnNewAd();
        }

        private void AdClick()
        {
            OnAdEngaged();
        }
        
#if DEBUG
        ~AdDuplexAdProvider()
        {
            Debug.WriteLine( Thread.CurrentThread.ManagedThreadId + "--Finalizing " + GetType().FullName);
        }
#endif
    }
}